use rand::RngCore;
use sha2::{Sha256, Digest};
use base64::{engine::general_purpose::URL_SAFE_NO_PAD, Engine};

use crate::db::{db_insert::db_insert, db_select::db_select};

#[derive(Debug)]
pub struct CodeChallenge {
    pub value: String,
    pub method: String,
    pub verifier: String,
}

impl CodeChallenge {
    pub async fn new() -> Self {
        // 尝试从数据库读取已有的 code_challenge
        if let Ok(config) = db_select("code_challenge_value").await {
            let verifier = db_select("code_challenge_verifier").await.unwrap().value;
            return CodeChallenge {
                value: config.value,
                method: "S256".to_string(),
                verifier,
            };
        }

        // 生成32字节的伪随机字节序列
        let mut code_verifier_bytes = [0u8; 32];
        rand::thread_rng().fill_bytes(&mut code_verifier_bytes);

        // 转换为 base64url 编码（无填充）
        let code_verifier = URL_SAFE_NO_PAD.encode(&code_verifier_bytes);

        // 使用 SHA-256 对编码后的字符串进行哈希
        let mut hasher = Sha256::new();
        hasher.update(code_verifier.as_bytes()); // ✅ 关键修改点
        let code_challenge_bytes = hasher.finalize();

        // 将哈希结果转换为 base64url 编码
        let code_challenge = URL_SAFE_NO_PAD.encode(&code_challenge_bytes);

        println!("Code Verifier: {}", code_verifier);
        println!("Code Challenge: {}", code_challenge);

        // 写入数据库
        db_insert("code_challenge_value", &code_challenge).await.unwrap();
        db_insert("code_challenge_method", "S256").await.unwrap();
        db_insert("code_challenge_verifier", &code_verifier).await.unwrap();

        CodeChallenge {
            value: code_challenge,
            method: "S256".to_string(),
            verifier: code_verifier,
        }
    }
}
